/*
 * EquipmentType.cpp
 *
 *  Created on: Oct 8, 2011
 *  Created by: Devin Manno
 *  Updated by: Devin Manno, Nick James
 *	Last Update: Nov 14, 2011
 */

#include "EquipmentType.h"
#include "Utility.h"

EquipmentType::EquipmentType() : Base("Equipment") {
	itemStats.setStats(0, 0, 0, 0, 0, 0);
	placeholder = false;	// not a placeholder

	int generateItem = Utility::getSeed(6);
	switch (generateItem){
        case 0:
            generateHelmet();		// generates a helmet
            break;
        case 1:
            generateChest();		// generates chest armor
            break;
        case 2:
            generateGloves();		// generates gloves
            break;
        case 3:
            generateBoots();		// generates boots
            break;
        case 4:
            generatePants();		// generates pants
            break;
        case 5:
            generateWeapon();		// generates a weapon
            break;
        default:
            break;
	}
}

EquipmentType::EquipmentType(itemSlot itemType) : Base("Equipment")
{
	placeholder = false;	// not a placeholder
	switch (itemType)
	{
		case HEAD:
			generateHelmet();		// generates a helmet
			break;
		case CHEST:
			generateChest();		// generates chest armor
			break;
		case GLOVES:
			generateGloves();		// generates gloves
			break;
		case FEET:
			generateBoots();		// generates boots
			break;
		case PANTS:
			generatePants();		// generates pants
			break;
		case WEAPON:
			generateWeapon();		// generates a weapon
			break;
	}
}

EquipmentType::EquipmentType(itemSlot whichSlot, bool placeholderOnly){
	placeholder = false;	// not a placeholder
	switch(whichSlot)
	{
		case HEAD:
			if(placeholderOnly){
				itemType = HEAD;
				makePlaceholder();
			}
			else
				generateHelmet();		// generates a helmet
			break;
		case CHEST:
			if(placeholderOnly){
				itemType = CHEST;
				makePlaceholder();
			}
			else
				generateChest();		// generates chest armor
			break;
		case GLOVES:
			if(placeholderOnly){
				itemType = GLOVES;
				makePlaceholder();
			}
			else
				generateGloves();		// generates gloves
			break;
		case FEET:
			if(placeholderOnly){
				itemType = FEET;
				makePlaceholder();
			}
			else
				generateBoots();		// generates boots
			break;
		case PANTS:
			if(placeholderOnly){
				itemType = PANTS;
				makePlaceholder();
			}
			else
				generatePants();		// generates pants
			break;
		case WEAPON:
			if(placeholderOnly){
				itemType = WEAPON;
				makePlaceholder();
			}
			else
				generateWeapon();		// generates a weapon
			break;
	}

}

EquipmentType::~EquipmentType(){

}

/*
 * makePlaceholder
 * Description: Makes the item a placeholder only, with no stats
 * Pre: none
 * Post: placeholder is set to true, all EquipmentStats are set to 0
 * 	and the name is set to "None"
 * Returns: none
 */
void EquipmentType::makePlaceholder(){
	placeholder = true;
	setDesc("None");
	itemStats.setAgility(0);
	itemStats.setStrength(0);
	itemStats.setIntelligence(0);
	itemStats.setConcentration(0);
	itemStats.setMaxHitPoints(0);
	itemStats.setMaxActionPoints(0);
	itemStats.setDamage(0);
	itemStats.setArmor(0);

}

int EquipmentType::getItemType()const{
	return itemType;
}

const Stats & EquipmentType::getItemStats()const{
	return itemStats;
}

/*
 * isPlaceholder
 * Description: returns placeholder
 * Pre: none
 * Post: none
 * Returns: placeholder; true if the item is a placeholder with 0 stats, false otherwise
 */
const bool EquipmentType::isPlaceholder(){
	return placeholder;
}

/* Finds ratio between level of item picked and size of vector it came from.  Level is
 * the position in the vector the item was in.  Items are stored in accending order.
 * It then multiplies this ratio to the maxBoost to find the new upper limit on the
 * amount of points this item can boost your stats. The higher the ratio, the higher
 * the upper limit will be.  The new upper limit will never go beyond maxBoost,
 * so the range will always be level to upperCap
 */
void EquipmentType::generate(int level, int size){
	float ratio;
	int upperCap;
	// prevent divide by 0 and get better ratio
	level++;

	ratio = level/size;
	// prevent ratio from going over 1 so final
	// number wont go above maxBoost
	if(ratio > 1)
		ratio = 1;
	upperCap = int(maxBoost*ratio) - level;

	itemStats.setAgility(level + (rand()% upperCap + 1));
	itemStats.setStrength(level + (rand()% upperCap + 1));
	itemStats.setIntelligence(level + (rand()% upperCap + 1));
	itemStats.setConcentration(level + (rand()% upperCap + 1));
	itemStats.setMaxHitPoints(level + (rand()% upperCap + 1));
	itemStats.setMaxActionPoints(level + (rand()% upperCap + 1));

	if(itemType == WEAPON)
		itemStats.setDamage(level + (rand()% upperCap + 1));  // Damaged need to be beefed up, not sure how.  Need some help from Nick.
	else
		itemStats.setArmor(level + (rand()% (upperCap-5) + 1));
}


void EquipmentType::generateHelmet(){
	std::vector<std::string> description; // helmet descriptions
	description.push_back("Salad Bowl");
	description.push_back("Rusty Helmet");
	description.push_back("Steel Helmet");
	description.push_back("Super Helmet");
	itemType = HEAD;

					// seed rand function
	long selector = Utility::getSeed((int)description.size()); 	// pick a helmet
	setDesc(description[selector]);
	generate((int)selector,(int)description.size());
	itemStats.setDamage(0);
}

void EquipmentType::generateChest(){
	std::vector<std::string> description; // helmet descriptions
	description.push_back("Leather Vest");
	description.push_back("Chain Mesh");
	description.push_back("Steel Plate");
	description.push_back("Force Field");
	itemType = CHEST;

					// seed rand function
	long selector = Utility::getSeed((int)description.size()); 	// pick a helmet
	setDesc(description[selector]);
	generate((int)selector,(int)description.size());
	itemStats.setDamage(0);
}
void EquipmentType::generateGloves(){
	std::vector<std::string> description; // helmet descriptions
	description.push_back("Cotton Mittens");
	description.push_back("Leather Gloves");
	description.push_back("Spiked Gloves");
	description.push_back("Brass Knuckles");
	itemType = GLOVES;

					// seed rand function
	long selector = Utility::getSeed((int)description.size()); 	// pick a helmet
	setDesc(description[selector]);
	generate((int)selector,(int)description.size());
	itemStats.setDamage(0);
}

void EquipmentType::generateBoots(){
	std::vector<std::string> description; // helmet descriptions
	description.push_back("Paper Bags");
	description.push_back("Clogs");
	description.push_back("Biker Boots");
	description.push_back("Jordans");
	itemType = FEET;

				// seed rand function
	long selector = Utility::getSeed((int)description.size()); 	// pick a helmet
	setDesc(description[selector]);
	generate((int)selector,(int)description.size());
	itemStats.setDamage(0);
}

void EquipmentType::generatePants(){
	std::vector<std::string> description; // helmet descriptions
	description.push_back("Swim Trunks");
	description.push_back("Parachute Pants");
	description.push_back("Levis");
	description.push_back("Diamond Pants");
	itemType = PANTS;

					// seed rand function
	long selector = Utility::getSeed((int)description.size()); 	// pick pants
	setDesc(description[selector]);
	generate((int)selector,(int)description.size());
	itemStats.setDamage(0);
}

void EquipmentType::generateWeapon(){
	std::vector<std::string> description; // weapon descriptions
	description.push_back("Fuzzy Dice");
	description.push_back("Wooden Stick");
	description.push_back("Wooden Mallet");
	description.push_back("Steel Sword");
	description.push_back("Diamond Sword");
	description.push_back("Flaming Electrical Sword");
	itemType = WEAPON;

					// seed rand function
	long selector = Utility::getSeed((int)description.size()); 	// pick a weapon
	setDesc(description[selector]);
	generate((int)selector,(int)description.size());
	itemStats.setArmor(0);
}

/*
 std::string EquipmentType::getClassName()const{
 return "EquipmentType";
 }
 */

std::ostream& operator<<(std::ostream& out, EquipmentType& e)
{
    out << e.Base::getDesc() << ',' << e.itemType
        << ',' << e.itemStats.getArmor() << ',' << e.itemStats.getDamage()
        << ',' << e.itemStats.getAgility() << ',' << e.itemStats.getStrength()
        << ',' << e.itemStats.getIntelligence() << ',' << e.itemStats.getConcentration()
        << ',' << e.itemStats.getMaxActionPoints() << ',' << e.itemStats.getMaxHitPoints();

    return out;
}

std::istream& operator>>(std::istream& in, EquipmentType &e)
{

    char *tk = NULL;// pointers to chars
    char data[MAX] = ""; //to hold line
    in.getline(data,MAX - 1, '\n');
    tk = strtok(data, DELIMS);  //get first token of new line
    e.setDesc(tk);
    tk = strtok(NULL, DELIMS); // get next token
    switch(atoi(tk))
    {
        case 0:
            e.itemType = HEAD;
            break;
        case 1:
            e.itemType = CHEST;
            break;
        case 2:
            e.itemType = GLOVES;
            break;
        case 3:
            e.itemType = FEET;
            break;
        case 4:
            e.itemType = PANTS;
            break;
        case 5:
            e.itemType = WEAPON;
            break;
    }
    tk = strtok(NULL, DELIMS); // get next token
    e.itemStats.setArmor(atoi(tk));
    tk = strtok(NULL, DELIMS); // get next token
    e.itemStats.setDamage(atoi(tk));
    tk = strtok(NULL, DELIMS); // get next token
    e.itemStats.setAgility(atoi(tk));
    tk = strtok(NULL, DELIMS); // get next token
    e.itemStats.setStrength(atoi(tk));
    tk = strtok(NULL, DELIMS); // get next token
    e.itemStats.setIntelligence(atoi(tk));
    tk = strtok(NULL, DELIMS); // get next token
    e.itemStats.setConcentration(atoi(tk));
    tk = strtok(NULL, DELIMS); // get next token
    e.itemStats.setMaxActionPoints(atoi(tk));
    tk = strtok(NULL, DELIMS); // get next token
    e.itemStats.setMaxHitPoints(atoi(tk));
    return in;
}
